<?php
/*
A to Z Listing Snippet for MODx Content Management Framework (http://modxcms.com)
Copyright (C) 2007 Garry Nutting
Version: 0.6

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/********************* Setup  ***************************/

//-- Alphabet Letters
$alphabet = array (
	"0-9",
	"A",
	"B",
	"C",
	"D",
	"E",
	"F",
	"G",
	"H",
	"I",
	"J",
	"K",
	"L",
	"M",
	"N",
	"O",
	"P",
	"Q",
	"R",
	"S",
	"T",
	"U",
	"V",
	"W",
	"X",
	"Y",
	"Z",
	"ALL"
);

//-- This is the entry in the $alphabet that returns the full listing
$all = "ALL";

//-- This is the entry in the $alphabet that returns non-alpha entries
$nonAlpha = '0-9';

//-- grouping option
$group = true;

//-- group template
$tplGroup = '<h3>[+letter+]</h3>';

//-- Gets the selected letter if a letter has been chosen
$letter = (isset ($_GET['letter'])) ? stripslashes($_GET['letter']) : '';

//-- Main column of the site_content table to return, suggested selections are: pagetitle, longtitle,
$title = (isset ($title)) ? stripslashes($title) : 'pagetitle';

//-- Message that gets displayed if no pages match the letter selected
$norecords = (isset ($norecords)) ? stripslashes($norecords) : 'No documents found for this letter';

//-- Introduction message, used when the page is first opened and no letter has been selected
$intro = (isset ($intro)) ? stripslashes($intro) : 'Please select a letter';

//-- Optional second column from the site_content table, for example, could be used to display the introtext
$summary = (isset ($summary)) ? stripslashes($summary) : 'introtext';

//-- Optional start id, can be used to specify a sub-folder for the A to Z
$startid = (isset ($startid)) ? stripslashes($startid) : 0;

//-- Used to determine if the 'hidemenu' option should be used, boolean value (DO NOT change line below)
$hidemenu = (isset ($hidemenu)) ? '' : ' AND hidemenu=0';

// separator for letters
$separator = ' | ';

//-- Results Template (separator is <!--separator--> and template is in three sections: pre results, result item, post results)
$tplResults = (isset ($tplResults)) ? $tplResults : false;
if ($tplResults !== false) {
	$template = $modx->getChunk($tplResults);
	$tplSplit = explode('<!--separator-->', $template);
	$tplPre = $tplSplit[0];
	$tplItem = $tplSplit[1];
	$tplPost = $tplSplit[2];
}

/********************* End of Setup ********************/

$lcount = count($alphabet); // number of letters in the alphabet

$empty = false; // for determining when no children exist for a start ID

$nonAlphaFilter = (in_array($nonAlpha, $alphabet)) ? '^[a-z]' : false; //sets the NOT RLIKE filter for non-alpha entries

//-- placeholder variables
$atozresults = '';
$atozletters = '';

//-- used for makeURL for current page
$docid = $modx->documentObject['id'];

if ($letter <> '') {
	# Processes subfolders if a $startid has been passed
	if (trim($startid) <> '') {
		//-- split out the start id values
		$startArray = explode(',', $startid);
		$atozarray = array();
		//-- loop through each start id
		foreach ($startArray as $startid) {
			//-- if not numeric, then loop now
			if (!is_numeric($startid))
				continue;
			$children = $modx->getChildIds($startid,10);
			$atozarray = array_merge($atozarray,$children);
		}

		//-- setup vars for array parsing
		$startwhere = '';
		$startcount = count($atozarray);
		$startloop = 0;

		//-- parse array into sql WHERE statement

		if (count($atozarray) == 1) {
			$startwhere = ' id="' . $atozarray[0] . '"';
		}
		elseif (count($atozarray) == 0) {
			$empty = true; //no values to return
		} else {
			foreach ($atozarray as $item) {
				if ($startloop == 0) {
					$startwhere .= ' id IN(' . $item;
					$startloop = $startloop +1;
				}
				elseif ($startloop == $startcount -1) {
					$startwhere .= $item.')';
					$startloop = $startloop +1;
				} else {
					$startwhere .=  $item . ',';
					$startloop = $startloop +1;
				}
			}
		}
	}
	
	# Main Processing
	//-- run SELECT query
	$table = $modx->getFullTableName("site_content");

	if (trim($startwhere) <> '') {
		//-- check for non-alpha request

		if ($letter == $nonAlpha) {
			$where = $title . ' NOT RLIKE \'' . $nonAlphaFilter . '\' AND published=1 AND deleted=0' . $hidemenu . ' AND privateweb=0 AND ' . $startwhere;
		} else {
			$where = $title . ' LIKE \'' . $letter . '%\' AND published=1 AND deleted=0' . $hidemenu . ' AND privateweb=0 AND ' . $startwhere;
		}
	} else {
		$where = $title . ' LIKE \'' . $letter . '%\' AND published=1 AND deleted=0' . $hidemenu . ' AND privateweb=0';
	}

	$orderby = $title . ' ASC';

	if ($letter <> $all) {
		$rs = $modx->db->select("*", $table, $where, $orderby);
	}
	elseif (trim($startwhere) <> '' && $letter == $all) {
		$rs = $modx->db->select("*", $table, "published=1 AND deleted=0" . $hidemenu . " AND privateweb=0 AND " . $startwhere, $orderby);

	} else {
		$rs = $modx->db->select("*", $table, "published=1 AND deleted=0" . $hidemenu . " AND privateweb=0", $orderby);
	}

	//-- get results
	$rscount = $modx->db->getRecordCount($rs);
	$atozresults .= $tplPre;

	if (!$empty && $rscount > 0) {
		while ($row = $modx->db->getRow($rs)) {

			//-- get the letter grouping
			if ($group) {
				preg_match('~\A.~i', $row[$title], $match);
				if (strtoupper($match[0]) !== strtoupper($lastLetter)) {
					if (preg_match('~[A-Za-z]~i', $match[0])) {
						$useLetter = str_replace('[+letter+]', strtoupper($match[0]), $tplGroup);
					} else {
						$useLetter = str_replace('[+letter+]', $nonAlpha, $tplGroup);
						$firstRun = false;
					}
				} else {
					$useLetter = '';
				}

				//-- get the letter for comparison in next loop
				preg_match('~\A.~i', $row[$title], $lastMatch);
				$lastLetter = $lastMatch[0];
			}

			//-- For MODx Repository: grab summary from the last release
			$where = 'parent="' . $row['id'] . '" AND isfolder=0 AND published=1 AND deleted=0' . $hidemenu . ' AND privateweb=0';
			$rsSum = $modx->db->select($summary, $table, $where, 'id DESC', '');
			if ($modx->db->getRecordCount($rsSum) > 0) {
				$rowSum = $modx->db->getRow($rsSum);
			}

			if ($tplResults) {
				$phArray = array (
					'[+aztitle+]',
					'[+azsummary+]',
					'[+azid+]',
					'[+groupletter+]'
				);
				$replaceArray = array (
					(trim($row[$title]
				) <> '') ? $row[$title] : $row['pagetitle'], $modx->stripTags($rowSum[$summary]), $row['id'], $useLetter);

				$atozresults .= str_replace($phArray, $replaceArray, $tplItem);
			} else {
				$atozresults .= '<ul class="azlist">';
				if (trim($row[$title]) <> '') {
					$atozresults .= '<li><a href="[~' . $row['id'] . '~]">' . $row[$title] . '</a></li>';
					if (trim($row[$summary]) <> '') {
						$atozresults .= '<ul><li>' . $rowSum[$summary] . '</li></ul>';
					}
				} else {
					$atozresults .= '<li><a href="[~' . $row['id'] . '~]">' . $row['pagetitle'] . '</a></li>';
					if (trim($row[$summary]) <> '') {
						$atozresults .= '<ul><li>' . $rowSum[$summary] . '</li></ul>';
					}
				}
				$atozresults .= '</ul>';
			}
		}
		if ($tplResults) {
			$atozresults .= $tplPost;
		}

	} else {
		//-- No Records returned from query
		$atozresults .= '<ul class="azlist"><li class="azitem">' . $norecords . '</li></ul>';
	}
} else {
	//-- No letter selected yet, display the intro text
	$atozresults .= '<ul class="azlist"><li>' . $intro . '</li></ul>';
}

//-- pull the pagetitles for link/no link status
$where = 'parent="' . $startid . '" AND published=1 AND deleted=0' . $hidemenu . ' AND privateweb=0';
$linkQuery = $modx->db->select($title, $modx->getFullTableName("site_content"), $where);

$groupLetterArray = array ();

if ($modx->db->getRecordCount($linkQuery) > 0) {
	while ($row = $modx->db->getRow($linkQuery)) {
		preg_match('~\A.~i', $row[$title], $match);
		if (preg_match('~[A-Za-z]~i', $match[0]) && !in_array(strtoupper($match[0]), $groupLetterArray)) {
			$groupLetterArray[] = strtoupper($match[0]);
		} else {
			$groupLetterArray[] = $nonAlpha;
		}
	}
}

//--push the ALL value into the array
$groupLetterArray[] = $all;

//-- Output Alphabet Headings
for ($i = 0; $i < $lcount; $i++) {
	if ($i < $lcount -1) {
		if (in_array(strtoupper($alphabet[$i]),$groupLetterArray)) {
			$atozletters .= '<span class="azalpha"><a href="' . $modx->makeURL($docid, '', 'letter=' . $alphabet[$i] . '') . '">' . $alphabet[$i] . '</a></span><span class="azsep">'.$separator.'</span>';
		} else {
			$atozletters .= '<span class="azalpha">' . $alphabet[$i] . '</span><span class="azsep">'.$separator.'</span>';
		}
	} else {
		if (in_array(strtoupper($alphabet[$i]),$groupLetterArray)) {
			$atozletters .= '<span class="azalpha"><a href="' . $modx->makeURL($docid, '', 'letter=' . $alphabet[$i] . '') . '">' . $alphabet[$i] . '</a></span>';
		} else {
			$atozletters .= '<span class="azalpha">' . $alphabet[$i] . '</span>';
		}
	}
}

//-- output to placeholders
$modx->setPlaceholder('atozletters', $atozletters);
$modx->setPlaceholder('atozresults', $atozresults);

return '';
?>